#include "ES.h"

ES::ES()
{
	curRecord = new XpensRecord();
	forTrash = new Trash();
	mySearch = new Search();

	string date;
	double totalExpens, income;
	ifstream infile("Figure.txt");
	if (!infile) {
		ofstream dataStorage("Expense.txt");
		ofstream payment("Payment.txt");
		ofstream Figure("Figure.txt");
//		income = 0;
		dataStorage.close();
		Figure.close();
	}
	else {
		infile >> income >> totalExpens;
//		infile >> totalExpens >> monthlyExpens >> dailyExpens >> date;
		curRecord -> getTracing() -> initialize(income, totalExpens);
		curRecord -> setCategory();
	}
	infile.close();
}
/*void ES::addIncome(double addValue)
{
	income += addValue;
	forTrash -> addOperation(1);
	forTrash -> add_lastIncome( addValue );
}*/

void ES::updateFigure()
{
	ofstream outfile("Figure.txt");
	outfile << fixed << setprecision(2) << curRecord -> getTracing() -> gettotalPayment() <<' ';
	outfile.flush();
	outfile << fixed << setprecision(2) << curRecord -> getTracing() -> gettotalXpens() << ' ';
//	outfile << curRecord -> getTracing() -> getDate();
	outfile.flush();
	outfile.close();
	curRecord -> saveExit();
}

void ES::undo()
{
	int operation;
	streampos address;
	operation = forTrash -> getOperation();
	
	if ( !operation ) cout << "Undo is not available!\n";
	else {
	if (operation == 1){ 
		curRecord -> getTracing() -> deleteTracing(forTrash -> getNewPayment());
		address = mySearch -> internalSearch(forTrash -> getNewPayment());
		curRecord -> updateItem(address, forTrash -> getOriginPayment());
	}
	else {
		curRecord -> getTracing() -> deleteTracing(forTrash -> getNewExpense());
		address = mySearch -> internalSearch(forTrash -> getNewExpense());
		curRecord -> updateItem(address, forTrash -> getOriginExpense());
	}
	}
}

void ES::redo()
{
	int operation;
	streampos address;
	operation = forTrash -> getRedoOperation();
	if (!operation) cout << "Redo is not available!\n";
	else {
	    if (operation == 1){
		curRecord -> getTracing() -> deleteTracing(forTrash -> getRedoNewPayment());
		address = mySearch -> internalSearch(forTrash -> getRedoNewPayment());
		curRecord -> updateItem(address, forTrash -> getRedoOriginPayment());
	}
	    else {
		curRecord -> getTracing() -> deleteTracing(forTrash -> getRedoNewExpense());
		address = mySearch -> internalSearch(forTrash -> getRedoNewExpense());
		curRecord -> updateItem(address, forTrash -> getRedoOriginExpense());
	}
	}
}

void ES::createExpense()
{
	XpensItem thisItem, emptyItem;
	curRecord -> createItem(thisItem);
	forTrash -> addOperation(-1);
	forTrash -> add_Expense(emptyItem, thisItem);
}

void ES::createPayment()
{
	PaymentItem thisItem, emptyItem;
	curRecord -> createItem(thisItem);
	forTrash -> addOperation(1);
	forTrash -> add_Payment(emptyItem, thisItem);
}

void ES::updateExpense(int updateID)
{
	XpensItem thisItem;
	thisItem.record();
	curRecord -> getTracing() -> deleteTracing(mySearch -> getExpItem(updateID));
	curRecord -> updateItem(mySearch -> getExpAddress(updateID), thisItem);
	forTrash -> addOperation(-1);
	forTrash -> add_Expense(mySearch -> getExpItem(updateID),thisItem);
}

void ES::updatePayment(int updateID)
{
	PaymentItem thisItem;
	thisItem.record();
	curRecord -> getTracing() -> deleteTracing(mySearch -> getPayItem(updateID));
	curRecord -> updateItem(mySearch -> getPayAddress(updateID), thisItem);
	forTrash -> addOperation(1);
	forTrash -> add_Payment(mySearch -> getPayItem(updateID), thisItem);
}

void ES::deleteExpense(int deleteID)
{
	XpensItem emptyItem;
	curRecord -> getTracing() -> deleteTracing(mySearch -> getExpItem(deleteID));
	curRecord -> updateItem(mySearch -> getExpAddress(deleteID),emptyItem);
	forTrash -> addOperation(-1);
	forTrash -> add_Expense(mySearch -> getExpItem(deleteID),emptyItem);
}

void ES::deletePayment(int deleteID)
{
	PaymentItem emptyItem;
	curRecord -> getTracing() -> deleteTracing(mySearch -> getPayItem(deleteID));
	curRecord -> updateItem(mySearch -> getPayAddress(deleteID),emptyItem);
	forTrash -> addOperation(1);
	forTrash -> add_Payment(mySearch -> getPayItem(deleteID),emptyItem);
}

void ES::TrackExpense(string date)
{
	mySearch -> expenseSearchDate(date);
	mySearch -> expensePrint();
}

void ES::TrackPayment(string date)
{
	mySearch -> paymentSearchDate(date);
	mySearch -> paymentPrint();
}
void ES::Alert()
{
	if (curRecord -> getTracing() -> gettotalXpens() > 0 && curRecord -> getTracing() -> gettotalXpens() > curRecord -> getTracing -> gettotalPayment() - 50)
		cout << "Caution! You have spent too much.\n Your total cash is less than 50 dollars!\n";
}

void ES::ReportDay(string date)
{
	cout << "Your total payment is " << fixed << setprecision(2) << curRecord -> getTracing() -> gettotalPayment() << ".\n";
	cout << "Your total expense is " << fixed << setprecision(2) << curRecord -> getTracing() ->gettotalXpens() << ".\n";
	
	cout << "Your total expense on " << date << "is "<< mySearch -> expenseSearchDate(date) << ".\n";
	cout << "Your total payment on " << date << "is "<< mySearch -> paymentSearchDate(date) << ".\n";
}

void ES::ReportMonth(int year, int month)
{
	static char m_months[13][10] = {"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

	cout << "Your total payment is " << fixed << setprecision(2) << curRecord -> getTracing() -> gettotalPayment() << ".\n";
	cout << "Your total expense is " << fixed << setprecision(2) << curRecord -> getTracing() ->gettotalXpens() << ".\n";
	cout << "Your total payment in " << m_months[month] << "is " << fixed << setprecision(2) << mySearch -> PaymentMonth(year, month) << ".\n";
	cout << "Your total expense in " << m_months[month] << "is " << fixed << setprecision(2) << mySearch -> ExpenseMonth(year, month) << ".\n";
}